class SnapshotSandbox {
  constructor(name) {
    this.name = name;
    this.proxy = window;
    this.modifyPropsMap = {};      // 记录被修改的 window 属性
    this.windowSnapshot = {};      // 快照存储
    this.activeTimers = [];        // 定时器 ID
    this.activeIntervals = [];     // interval ID
    this.activeRAF = [];           // requestAnimationFrame ID
    this.prototypeSnapshot = {};   // 原型快照

    this.patchAsyncMethods();
  }

  // 拦截异步任务，记录 ID 方便清理
  patchAsyncMethods() {
    const rawSetTimeout = window.setTimeout;
    const rawSetInterval = window.setInterval;
    const rawRAF = window.requestAnimationFrame;

    window.setTimeout = (...args) => {
      const id = rawSetTimeout(...args);
      this.activeTimers.push(id);
      return id;
    };

    window.setInterval = (...args) => {
      const id = rawSetInterval(...args);
      this.activeIntervals.push(id);
      return id;
    };

    window.requestAnimationFrame = (cb) => {
      const id = rawRAF(cb);
      this.activeRAF.push(id);
      return id;
    };

    this._clearAsync = () => {
      this.activeTimers.forEach(clearTimeout);
      this.activeIntervals.forEach(clearInterval);
      this.activeRAF.forEach(cancelAnimationFrame);
      this.activeTimers.length = 0;
      this.activeIntervals.length = 0;
      this.activeRAF.length = 0;
    };
  }

  // 激活沙箱（进入子应用）
  active() {
    console.log(`[${this.name}] sandbox active`);
    // 保存当前 window 快照
    this.windowSnapshot = {};
    for (const prop in window) {
      if (Object.prototype.hasOwnProperty.call(window, prop)) {
        this.windowSnapshot[prop] = window[prop];
      }
    }
    // 保存原型链快照（Object / Array）
    this.prototypeSnapshot.Object = { ...Object.prototype };
    this.prototypeSnapshot.Array = { ...Array.prototype };

    // 恢复上一次的修改
    Object.keys(this.modifyPropsMap).forEach(prop => {
      window[prop] = this.modifyPropsMap[prop];
    });
  }

  // 失活沙箱（退出子应用）
  inactive() {
    console.log(`[${this.name}] sandbox inactive`);
    // 清理所有异步任务
    this._clearAsync();

    // 还原 window 的同步修改
    for (const prop in window) {
      if (Object.prototype.hasOwnProperty.call(window, prop)) {
        if (window[prop] !== this.windowSnapshot[prop]) {
          this.modifyPropsMap[prop] = window[prop]; // 保存修改
          window[prop] = this.windowSnapshot[prop]; // 还原
        }
      }
    }

    // 还原原型链污染
    Object.keys(this.prototypeSnapshot.Object).forEach(key => {
      Object.prototype[key] = this.prototypeSnapshot.Object[key];
    });
    Object.keys(this.prototypeSnapshot.Array).forEach(key => {
      Array.prototype[key] = this.prototypeSnapshot.Array[key];
    });
  }
}
